﻿using Common.EF;
using Common.Infrastructure;
using Common.Infrastructure.Service;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Common.AspNetCore
{
    public class CommonService : ICommonService
    {
        private readonly IServiceProvider provider;

        private readonly ILogService log;

        private readonly ICommonRepository commonRepository;

        private readonly IServiceCallService serviceCall;

        private readonly IUserTokenService userToken;

        public CommonService(IServiceProvider provider)
        {
            this.provider = provider;
            if (provider != null)
            {
                this.log = provider.GetService<ILogService>();
            }

            if (provider != null)
            {
                var p = new CommonContextPoolParam(provider, null);
                if (p.Contexts.Any(t => t.ContextType == ContextTypeEnum.DefaultContext))
                {
                    this.commonRepository = provider.GetService<ICommonRepository>();
                }
            }

            if (provider != null)
            {
                this.serviceCall = provider.GetService<IServiceCallService>();
            }

            if (provider != null)
            {
                this.userToken = provider.GetService<IUserTokenService>();
            }
        }

        protected IServiceProvider Provider
        {
            get { return this.provider; }
        }

        protected ILogService Log
        {
            get { return this.log; }
        }

        protected IServiceCallService CallService
        {
            get { return this.serviceCall; }
        }

        protected UserToken UserToken
        {
            get { return this.userToken?.GetUserToken(); }
        }

        protected bool HasThrow
        {
            get { return LibMessageUtils.HasError(this.provider); }
        }

        #region 信息

        protected void AddError(string message)
        {
            LibMessageUtils.AddError(this.provider, message);
        }

        protected void AddError(string code, params object[] objs)
        {
            LibMessageUtils.AddError(this.provider, code, objs);
        }

        protected void AddWarning(string message)
        {
            LibMessageUtils.AddWarning(this.provider, message);
        }

        protected void AddWarning(string code, params object[] objs)
        {
            LibMessageUtils.AddWarning(this.provider, code, objs);
        }

        protected void AddInfomation(string message)
        {
            LibMessageUtils.AddInfomation(this.provider, message);
        }

        protected void AddInfomation(string code, params object[] objs)
        {
            LibMessageUtils.AddInfomation(this.provider, code, objs);
        }

        protected string GetMessage(string code, params object[] objs)
        {
            return LibMessageUtils.GetMessage(this.provider, code, objs);
        }

        protected void ThrowError(string code, params object[] objs)
        {
            LibMessageUtils.ThrowError(this.provider, code, objs);
        }
        #endregion

        #region 编码

        protected string GetSerial(string typeCode)
        {
            return LibSerialUtils.GetSerial(this.provider, typeCode);
        }

        protected List<string> GetSerials(string typeCode, int count)
        {
            return LibSerialUtils.GetSerials(this.provider, typeCode, count);
        }

        #endregion

        protected void SetEntityId<T>(T t, string parentId = null) where T : EntityBase, new()
        {
            var s = this.commonRepository.GetEntityIds(new IDParam() { Count = 1, EntityName = typeof(T).Name, ParentId = parentId });
            if (s.Any())
            {
                t.id = s[0];
            }
        }

        protected void SetEntitiesId<T>(List<T> entities, string parentId = null) where T : EntityBase, new()
        {
            var s = this.commonRepository.GetEntityIds(new IDParam() { Count = entities.Count, EntityName = typeof(T).Name, ParentId = parentId });
            if (!s.Any())
            {
                return;
            }

            int i = 0;
            s.ForEach(t =>
            {
                entities[i].id = t;
                i++;
            });
        }

        protected List<string> GetEntityIds(IDParam idparam)
        {
            return this.commonRepository.GetEntityIds(idparam);
        }

        #region 消息
        protected async Task MQPublishAsync<T>(string name, T contentObj, string callbackName = null, CancellationToken cancellationToken = default)
        {
            await LibMQUtils.PublishAsync(this.Provider, name, contentObj, callbackName, cancellationToken);
        }

        protected async Task MQPublishAsync<T>(string name, T contentObj, IDictionary<string, string> headers, CancellationToken cancellationToken = default)
        {
            await LibMQUtils.PublishAsync(this.Provider, name, contentObj, headers, cancellationToken);
        }

        protected void MQPublish<T>(string name, T contentObj, string callbackName = null)
        {
            LibMQUtils.Publish(this.Provider, name, contentObj, callbackName);
        }

        protected void MQPublish<T>(string name, T contentObj, IDictionary<string, string> headers)
        {
            LibMQUtils.Publish(this.Provider, name, contentObj, headers);
        }
        #endregion
    }
}
